﻿// ------------------------------------------------------------------------------------------------
//  <copyright file="Runtime.cs" company="Iveely">
//    Copyright (c) Iveely Liu.  All rights reserved.
//  </copyright>
//  
//  <Create Time>
//    03/02/2013 21:59 
//  </Create Time>
//  
//  <contact owner>
//    liufanping@iveely.com 
//  </contact owner>
//  -----------------------------------------------------------------------------------------------

#region

using System;
using System.Collections.Generic;
using System.Threading;
using IveelySE.Common;

#endregion

namespace IveelySE.Run.Task
{
    /// <summary>
    ///   执行机
    /// </summary>
    public class Runtime
    {
        /// <summary>
        ///   在同一时刻允许最大的执行任务数量
        /// </summary>
        private static int MaxSubmit = 10;

        /// <summary>
        ///   执行的任务集合
        /// </summary>
        private static readonly List<Schedule> List = new List<Schedule>();

        /// <summary>
        ///   初始化操作
        /// </summary>
        public static void Initialization()
        {
            //List = new Hashtable();
            var checkSchedule = new Thread(CheckSchedule);
            checkSchedule.Start();
            //CheckSchedule();
        }

        /// <summary>
        ///   创建新的计划任务（默认1个小时执行一次）
        /// </summary>
        public static void CreateSchedule<T>(double minute = 60, double maxRunning = 60*24, bool rightNow = false)
            where T : ITask
        {
            var schedule = new Schedule();
            //设定当前时间为上次执行时间
            schedule.LastSubmit = rightNow ? DateTime.MaxValue : DateTime.Now;
            //设定执行间隔时间
            schedule.Minute = minute;
            //设定最大执行时间
            schedule.MaxRunning = maxRunning;
            //设定执行任务的实体
            object activator = Activator.CreateInstance(typeof(T));
            var itask = activator as ITask;
            schedule.Task = itask;
            schedule.Name = itask.Name;
            //加入任务集合中
            List.Add(schedule);
        }

        /// <summary>
        ///   检查需要执行的任务
        /// </summary>
        private static void CheckSchedule()
        {
            while(true)
            {
                DateTime dt = DateTime.Now;
                for(int i = 0; i < List.Count; i++)
                {
                    Schedule schedule = List[i];
                    double minute = (dt - schedule.LastSubmit).TotalMinutes;
                    //如果任务没有在执行状态 且 已经超过了运行间隔
                    if(schedule.Status != Schedule.State.Running &&
                       (minute >= schedule.Minute || schedule.LastSubmit == DateTime.MaxValue))
                    {
                        Console.WriteLine(DateTime.Now.ToString() + ":" + schedule.Name + "正在执行。");
                        schedule.Status = Schedule.State.Running;
                        schedule.Start();
                    }
                        //如果任务正在运行，且程序运行结束
                    else if(schedule.Status == Schedule.State.Running && !schedule.Task.IsAlive())
                    {
                        //则显示记录为已经结束
                        schedule.Status = Schedule.State.Compelete;
                        //记录本次结束时间
                        schedule.LastSubmit = DateTime.Now;
                        //再次让它结束
                        schedule.Stop();
                    }
                        ////如果任务正在运行，但是超过了我们最大允许的运行时间，则无条件结束
                    else if(schedule.Status == Schedule.State.Running && minute > schedule.MaxRunning)
                    {
                        schedule.LastSubmit = dt;
                        schedule.Status = Schedule.State.Queue;
                        schedule.Stop();
                    }
                    List[i] = schedule;
                }
            }
        }
    }
}